<template>
  <div ref="artListDiv" class="artList">
    <!-- 下拉更新组件 -->
    <van-pull-refresh
      :success-duration="1000"
      :success-text="sucText"
      v-model="refreshing"
      @refresh="onRefresh"
    >
      <!-- 文章列表组件 -->
      <van-list
        :error.sync="isError"
        error-text="请求失败，点击重新加载"
        v-model="loading"
        :finished="finished"
        finished-text="没有更多了"
        @load="onLoad"
      >
        <!-- 文章项组件 -->
        <ArtItem v-for="(art, i) in list" :key="i" :article="art" />
      </van-list>
    </van-pull-refresh>
  </div>
</template>

<script>
import { getChannelArtList } from '@/api/article.js';
import { setItem, getItem } from '@/utils/storage.js';

// 导入 文章列表项 组件
import ArtItem from '@/components/article-item/index.vue';

export default {
  name: 'article-list',
  // 注册组件
  components: {
    ArtItem,
  },
  // 声明 属性，供给 父组件传参使用
  props: ['channel'], // {id:1,name:'html'}
  data() {
    return {
      refreshing: false,
      sucText: '加载成功啦~！',
      list: [],
      loading: false,
      finished: false,
      pre_time: Date.now(),
      isError: false, // 是否显示 触底加载失败消息
    };
  },
  methods: {
    // 下拉更新
    async onRefresh() {
      try {
        // 随机模拟报错
        if (Math.random() >= 0.9) {
          throw new Error('模拟随机报错啦~！');
        }

        // a.用当前时间戳，请求最新的 数据
        const { data: resBody } = await getChannelArtList(
          this.channel.id,
          Date.now()
        );

        let newList = resBody.data.results;

        // 2.将返回的 最新文章 从 数组头部 加入
        this.list.unshift(...newList);

        // 3.关闭 下拉刷新中 状态，会显示 成功文案
        this.refreshing = false;
        // 修改成功文案
        this.sucText = '加载成功啦~！';
      } catch (error) {
        // 关闭 下拉刷新中 状态，会显示 成功文案
        this.refreshing = false;
        // 修改成功文案
        this.sucText = '加载报错了~~！';
        console.log('报错啦：', error.message);
      }
    },
    // 触底更新
    async onLoad() {
      try {
        // 随机模拟报错
        if (Math.random() >= 0.8) {
          throw new Error('模拟随机报错啦~！');
        }

        // 1.请求 频道文章 接口 ------------------
        // 注意：由于aioxs 直接拿到的 是 响应对象，我们可以结构 其中的 data属性，设置给resBody变量
        const { data: resBody } = await getChannelArtList(
          this.channel.id,
          this.pre_time
        );
        // 2.打印 响应报文体中的 data
        this.list.push(...resBody.data.results);
        // 3.将返回的 下一页时间戳 给 data
        this.pre_time = resBody.data.pre_timestamp;
        // 3.手动将 加载状态 改成 false，代表 加载完毕
        this.loading = false;
      } catch (error) {
        console.log('出错啦：', error.message);
        // 显示 加载错误提示
        this.isError = true;
        // 关闭加载状态
        this.loading = false;
      }
    },
  },
  // 组件的入口函数(钩子函数之一：)
  // 业务实现的大入口思维： 什么时候，做什么事情！
  async created() {},
  mounted() {
    // {channel.id:100,channel.id:200} , []
    // 当 列表组件被渲染成真实dom时，就为 当前 div容器 绑定 滚动事件
    this.$refs.artListDiv.onscroll = (e) => {
      // a.先读取 本地保存的 高度数据
      let topDataList = getItem('1008scrollTop');
      !topDataList && (topDataList = {});
      // b.再 设置 当前频道的 高度数据 topDataList.1 = 100
      topDataList[this.channel.id] = e.target.scrollTop;
      // c.最后 将 新的 高度数据对象 重新保存到 本地
      setItem('1008scrollTop', topDataList);
    };
  },
  // 当 组件 从 keepalive缓存中 重新渲染出来，就会执行
  activated() {
    // 从本地 读取 高度数据
    let topDataList = getItem('1008scrollTop');
    // 如果存在，则 把本频道的 高度取出，设置给本频道的 div
    if (topDataList) {
      this.$refs.artListDiv.scrollTop = topDataList[this.channel.id];
    }
  },
};
</script>

<style lang="less" scoped>
.artList {
  height: 80vh;
  overflow-y: auto;
}
</style>
